import os
import json
from collections import Counter
from PyQt5.QtCore import QThread, pyqtSignal
from PyQt5.QtWidgets import QMessageBox
from socre.score_plus import process_file
from control.Databasemanage import DatabaseManager
from test_api import getdir
import logging

db_manager = DatabaseManager()
db_manager.connect()
cursor = db_manager.connection.cursor()

class WorkerThread(QThread):
    result_signal = pyqtSignal(object)
    pause_changed = pyqtSignal(object)
    show_popup_signal = pyqtSignal(str, str)
    error_signal = pyqtSignal(str)
    success_signal = pyqtSignal(str)
    stop_signal = pyqtSignal()
    finishedmessage = pyqtSignal()

    def __init__(self, folder_path, completed_tasks, parent=None):
        super(WorkerThread, self).__init__(parent)
        logging.debug("Initializing WorkerThread")
        self.folder_path = folder_path
        self.is_stopped = False
        self.completed_tasks = completed_tasks

    def run(self):
        try:
            logging.debug("WorkerThread started")
            for work in self.folder_path:
                if self.is_stopped:
                    logging.debug("Stopping WorkerThread")
                    self.stop_signal.emit()
                    break
                if work in self.completed_tasks:
                    logging.debug(f"Task already completed: {work}")
                    continue  # 如果任务已经完成，则跳过

                logging.debug(f"Processing task: {work}")
                path_name = os.path.basename(work)
                name = path_name.split('.')[0]
                part = name.split('_')

                subject_code = part[0]
                student_id = part[2]
                year = part[1]
                answer_qr_code = part[7]
                logging.debug(f"Extracted values: subject_code={subject_code}, student_id={student_id}, year={year}, answer_qr_code={answer_qr_code}")

                cursor.execute("SELECT paper_id FROM exam_answer_paper WHERE subject_code = ?", (subject_code,))
                paper_id_result = cursor.fetchone()
                if not paper_id_result:
                    logging.error(f"No paper_id found for subject_code: {subject_code}")
                    continue

                paper_id = paper_id_result[0]
                logging.debug(f"Found paper_id: {paper_id}")

                cursor.execute(
                    "SELECT answer_id, answer_no, answer_score, parent_answer_id FROM exam_answer_into WHERE paper_id = ? AND answer_qr_code = ?",
                    (paper_id, answer_qr_code))
                answer_id_result = cursor.fetchall()
                logging.debug(f"Found answer_id_result: {answer_id_result}")

                answer_standards = {}
                for answer_id, _, _, _ in answer_id_result:
                    cursor.execute("SELECT answer_standard FROM exam_answer_standard WHERE paper_id = ? AND answer_id = ?",
                                   (paper_id, answer_id))
                    result = cursor.fetchone()
                    if result:
                        answer_standards[answer_id] = result[0]
                    else:
                        logging.warning(f"No answer_standard found for answer_id: {answer_id}")

                updated_data = []
                for answer_id, tid, score, parent_answer_id in answer_id_result:
                    answer_standard = answer_standards.get(answer_id, None)
                    updated_data.append((paper_id, tid, score, answer_id, answer_standard, parent_answer_id))

                tid_to_standard = {str(tid): f"{answer_standard}-{score}-{answer_id}-{score}-{paper_id}-{parent_answer_id}"
                                   for paperid, tid, score, answer_id, answer_standard, parent_answer_id in updated_data}

                correct_answers = list(tid_to_standard.values())
                score_1 = [(i + 1, float(answer.split('-')[1])) for i, answer in enumerate(correct_answers)]
                score_2 = [(i + 1, int(float(answer.split('-')[2]))) for i, answer in enumerate(correct_answers)]
                score_3 = [(i + 1, int(float(answer.split('-')[5]))) for i, answer in enumerate(correct_answers)]
                paperId = list(tid_to_standard.values())[0].split('-')[-2]
                parent_answer_id = list(tid_to_standard.values())[0].split('-')[-1]
                correct_answers_with_index = [(score_2[i][1], score_1[i][1], answer.split('-')[0], score_3[i][1]) for
                                              i, answer in enumerate(correct_answers)]

                logging.debug(f"correct_answers_with_index: {correct_answers_with_index}")

                self.settings_file = getdir() + 'api/ConfigJson.txt'
                with open(self.settings_file, 'r', encoding='utf-8') as file:
                    settings = json.load(file)
                filepath_prefix = settings.get("filepath", "")
                filepath = os.path.join(filepath_prefix, work)

                if not os.path.exists(filepath):
                    logging.error(f"File does not exist: {filepath}")
                    continue

                self.result_answer = process_file(filepath, correct_answers_with_index, subject_code, student_id,
                                                  paperId, answer_qr_code, parent_answer_id)

                cursor.execute(
                    "SELECT paper_no, exam_year FROM exam_subject_student WHERE paper_id = ? AND subject_code = ? AND student_id = ?",
                    (paper_id, subject_code, student_id))
                results = cursor.fetchone()
                if not results:
                    logging.error(f"No results found for paper_id={paper_id}, subject_code={subject_code}, student_id={student_id}")
                    continue

                paper_no = results[0]
                exam_year = results[1]

                if len(self.result_answer) != 0 and "Fail to deal with" not in self.result_answer:
                    contains_none = any(element.split('_')[4] == "None" for element in self.result_answer)
                    if contains_none:
                        self.Marking_error(exam_year, student_id, paper_id, subject_code, parent_answer_id, paper_no, work)
                    else:
                        self.Mark_correctly(exam_year, student_id, paper_id, subject_code, parent_answer_id, paper_no, work)
                else:
                    self.Marking_error(exam_year, student_id, paper_id, subject_code, parent_answer_id, paper_no, work)

                self.completed_tasks.append(work)
                if Counter(self.completed_tasks) == Counter(self.folder_path):
                    self.finishedmessage.emit()

        except Exception as e:
            logging.error(f"Error in WorkerThread: {e}", exc_info=True)
            self.error_signal.emit(str(e))

    def Marking_error(self, exam_year, student_id, paper_id, subject_code, parent_answer_id, paper_no, filepath):
        logging.error(f"Marking error: {filepath}")
        self.error_signal.emit(filepath)

        try:
            cursor.execute("""
                UPDATE exam_scan_split
                SET split_answer_status = 2
                WHERE exam_year = ? AND student_id = ? AND paper_id = ? AND subject_code = ? AND answer_id = ?
            """, (exam_year, student_id, paper_id, subject_code, parent_answer_id))
            db_manager.connection.commit()

            cursor.execute("""
                UPDATE exam_subject_paper_initialize
                SET split_answer_check_status = 2
                WHERE exam_year = ? AND student_id = ? AND paper_id = ? AND subject_code = ? AND answer_id = ? AND paper_no = ?
            """, (exam_year, student_id, paper_id, subject_code, parent_answer_id, paper_no))
            db_manager.connection.commit()
        except Exception as e:
            logging.error(f"Error updating database in Marking_error: {e}", exc_info=True)
            db_manager.connection.rollback()

    def Mark_correctly(self, exam_year, student_id, paper_id, subject_code, parent_answer_id, paper_no, filepath):
        logging.debug(f"Marking correctly: {filepath}")
        self.success_signal.emit(filepath)

        try:
            cursor.execute("""
                UPDATE exam_scan_split
                SET split_answer_status = 1
                WHERE exam_year = ? AND student_id = ? AND paper_id = ? AND subject_code = ? AND answer_id = ?
            """, (exam_year, student_id, paper_id, subject_code, parent_answer_id))
            db_manager.connection.commit()

            cursor.execute("""
                UPDATE exam_subject_paper_initialize
                SET split_answer_check_status = 1
                WHERE exam_year = ? AND student_id = ? AND paper_id = ? AND subject_code = ? AND answer_id = ? AND paper_no = ?
            """, (exam_year, student_id, paper_id, subject_code, parent_answer_id, paper_no))
            db_manager.connection.commit()
        except Exception as e:
            logging.error(f"Error updating database in Mark_correctly: {e}", exc_info=True)
            db_manager.connection.rollback()

    def stop(self):
        logging.debug("Stopping WorkerThread")
        self.is_stopped = True